package com.az.miaoauth.service.impl;

import cn.hutool.core.lang.Validator;
import com.az.emailcommon.util.EmailSender;
import com.az.miaoapi.exception.BaseException;
import com.az.miaoapi.response.ResponseCode;
import com.az.miaoauth.domain.dto.EmailCodeDto;
import com.az.miaoauth.service.EmailService;
import jakarta.mail.MessagingException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.MailSendException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class EmailServiceImpl implements EmailService {

    private final EmailSender emailSender;
    private final RedisTemplate<String, Object> redisTemplate;

    @Override
    @Retryable(noRetryFor = BaseException.class)
    public void sendVerificationCode(String emailTo) {

        if (!Validator.isEmail(emailTo)) {
            throw new BaseException(ResponseCode.EMAIL_ILLEGAL);
        }

        String verificationCode = String.format("%06d", (int) (Math.random() * 1000000));

        String msg = "<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
                "    <title>验证码邮件</title>\n" +
                "    <style>\n" +
                "        body {\n" +
                "            font-family: Arial, sans-serif;\n" +
                "            background-color: #f4f4f4;\n" +
                "            margin: 0;\n" +
                "            padding: 0;\n" +
                "            text-align: center;\n" +
                "        }\n" +
                "        .container {\n" +
                "            width: 80%;\n" +
                "            max-width: 600px;\n" +
                "            margin: 20px auto;\n" +
                "            background: #ffffff;\n" +
                "            padding: 20px;\n" +
                "            border-radius: 8px;\n" +
                "            box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n" +
                "        }\n" +
                "        h2 {\n" +
                "            color: #333333;\n" +
                "        }\n" +
                "        .code {\n" +
                "            font-size: 24px;\n" +
                "            font-weight: bold;\n" +
                "            color: #4CAF50;\n" +
                "            padding: 10px;\n" +
                "            border: 2px solid #4CAF50;\n" +
                "            border-radius: 4px;\n" +
                "            display: inline-block;\n" +
                "            margin-top: 10px;\n" +
                "        }\n" +
                "        p {\n" +
                "            color: #555555;\n" +
                "        }\n" +
                "    </style>\n" +
                "</head>\n" +
                "<body>\n" +
                "    <div class=\"container\">\n" +
                "        <h2>您的验证码</h2>\n" +
                "        <div class=\"code\">" + verificationCode + "</div>\n" +
                "        <p>请手动复制上面的验证码，并在网站上输入。</p>\n" +
                "    </div>\n" +
                "</body>\n" +
                "</html>";

        try {
            emailSender.sendHTMLEmail(emailTo, "验证码", msg);
        } catch (MailSendException | MessagingException e) {
            throw new BaseException(ResponseCode.SEND_EMAIL_FAIL);
        }
        String keyPrefix = "code:";
        redisTemplate.opsForValue().set(keyPrefix + emailTo, verificationCode, 5, TimeUnit.MINUTES);

    }
    @Override
    @Retryable(noRetryFor = BaseException.class)
    public void bindEmailCode(EmailCodeDto emailCodeDto) {
        if (!emailCodeDto.getCode().equals(Optional
                .ofNullable(redisTemplate.opsForValue().get("code:" + emailCodeDto.getEmail()))
                .orElseThrow(() -> new BaseException(ResponseCode.CODE_OVERDUE)))) {
            throw new BaseException(ResponseCode.LOGIN_FAILED);
        }
        redisTemplate.delete("code:" + emailCodeDto.getEmail());
    }

}
